﻿using System;
using System.Linq.Expressions;
using Glue.Internals;
using Xunit;

namespace GlueTests.LambdaDecomposerTests
{
    public class When_decomposing_a_casted_type
    {
        public class TheClass:ITheClass
        {
            public int AField = 1;
            public String TheProperty { get; set; }
            public decimal AMethod() { return 0; }
            public AnotherClass Nested { get; set; }
        }

        public interface ITheClass
        {
            String TheProperty { get; set; }
            decimal AMethod();
            AnotherClass Nested { get; set; }
        }

        public class AnotherClass:IAnotherClass
        {
            public int AField = 1;
            public String TheProperty { get; set; }
            public decimal AMethod() { return 0; }
        }

        public interface IAnotherClass
        {
            String TheProperty { get; set; }
            decimal AMethod();
        }

        [Fact]
        public void Should_find_property()
        {
            Func<TheClass, String> func = x => x.TheProperty;
            CastProperty(func);
            
        }

        private void CastProperty<T1>(  Func <T1, String> func) where T1:ITheClass
        {
            Expression<Func<T1, String>> castedFunc = x => x.TheProperty;
            var decomposer = new LambdaDecomposer(castedFunc);
            Assert.NotNull(decomposer.GetAccessor());
        }

        [Fact]
        public void Should_find_method()
        {
            Func<TheClass, decimal> func = x => x.AMethod();
            CastMethod(func);
        }

        private void CastMethod<T1>(Func<T1, decimal> func) where T1 : ITheClass
        {
            Expression<Func<T1, decimal>> castedFunc = x => x.AMethod();
            var decomposer = new LambdaDecomposer(castedFunc);
            Assert.NotNull(decomposer.GetAccessor());

        }

        [Fact]
        public void Should_find_nested_property()
        {
            Func<TheClass, String> func = x => x.Nested.TheProperty;
            CastNestedProperty(func);
        }

        private void CastNestedProperty<T1>(Func<T1, String> func) where T1 : ITheClass
        {
            Expression<Func<T1, String>> castedFunc = x => x.Nested.TheProperty;
            var decomposer = new LambdaDecomposer(castedFunc);
            Assert.NotNull(decomposer.GetAccessor());

        }

        [Fact]
        public void Should_find_nested_method()
        {
            Func<TheClass, decimal> func = x => x.Nested.AMethod();
            CastNestedMethod(func);
        }

        private void CastNestedMethod<T1>(Func<T1, decimal> func) where T1 : ITheClass
        {
            Expression<Func<T1, decimal>> castedFunc = x => x.Nested.AMethod();
            var decomposer = new LambdaDecomposer(castedFunc);
            Assert.NotNull(decomposer.GetAccessor());

        }
    }
}
